#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "carte.h"
#include "listecartecourrier.h"
#include "pion.h"

/**
@brief Cette fonction définit le module listecarte
@author MARLIER Molly & GUESDON Marine
@version 1.0
@date 2013/03/26
*/

/**
@brief InitialiserListe permet d'initialiser la liste pour qu'elle soit vide.
@param [in] l: pointeur sur liste.
@return none.
*/
void initialiserListeC(ListeCourrier * l)
{
    l->prem=NULL;
    l->last=NULL;

}

/**
@brief ImplementeListeC permet de remplir la pioche courrier avec les cartes courrier que nous avons choisi.
@param [in] l: pointeur sur liste.
@return none.
*/
void ImplementeListeC (ListeCourrier *l)
{
    initialiserListeC(l);
    CarteCourrier temp;
    InitCarteC (&temp, 1, -50);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 2, -50);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 3, 0);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 4, -60);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 5, 0);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 6, -100);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 7, -300);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 8, -150);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 9, 200);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 10, -400);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 11, -300);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 12, -250);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 13, 0);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 14, -100);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 15, -150);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 16, 0);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 17, -100);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 18, 50);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 19, -200);
    AjouterEnTeteListeC(temp ,l);
    InitCarteC (&temp, 20, -400);
    AjouterEnTeteListeC(temp ,l);

}

/**
@brief AjouterEnTeteListe aoute une carte en tête de la liste.
@param [in] l: pointeur sur liste, [in] c:Carte.
@return none.
*/
/* Precondition : l et e initialises et manipules uniquement a travers les operations de leurs modules respectifs*/
void AjouterEnTeteListeC(CarteCourrier c,ListeCourrier * l)
{
    CelluleCourrier *temp;
    temp=l->prem;
    l->prem= (CelluleCourrier*)malloc(sizeof(CelluleCourrier));
    l->prem->info=c;
    l->prem->precedent=NULL;
    if(l->last==NULL)
    {
        l->last=l->prem;
        l->prem->suivant=NULL;
    }
    else
    {
        l->prem->suivant=temp;
        temp->precedent=l->prem;
    }
}


/**
@brief AjouterEnQueueListe ajoute une carte en queue de liste.
@param [in] l: pointeur sur liste, [in] c:Carte.
@return none.
*/
void AjouterEnQueueListeC(CarteCourrier e, ListeCourrier * l) {
CelluleCourrier* temp ;
temp=(CelluleCourrier*) malloc (sizeof (CelluleCourrier)) ;
temp->info=e ;
temp->suivant=NULL ;
temp->precedent=l->last ;
if(EstVideListeC(l))
    {l->prem=temp ;}
else {l->last->suivant=temp ;}
l->last=temp ;}

/**
@brief EstVideListe permet de teste si la liste est vide: renvoi 1 si elle l'est 0 sinon
@param [in,out] l: pointeur sur liste,
@return int
*/
int EstVideListeC(const ListeCourrier * l)
/* Precondition : l prealablement initialisee et manipulee uniquement
                  a travers les operations du module
   Resultat : 1 si l est vide, 0 sinon */
{
    int i;
    if ((l->prem== NULL) && (l->last==NULL))
        {
            i=1;
        }
    else
        {
            i=0;
        }
    return i;
}

/**
@brief SupprimerTeteListe supprime le premier élément dde la liste
@param [in] l: pointeur sur liste
@return none.
*/
/* Precondition : l n'est pas vide*/
void SupprimerTeteListeC(ListeCourrier * l)
{
    assert (EstVideListeC(l)==0);
    CelluleCourrier *temp1;
    CelluleCourrier *temp2;
    temp1=l->prem;
    if(l->last == temp1)
    {
        l->last=NULL;
        l->prem=NULL;
    }
    else
    {
        temp2=temp1->suivant;
        l->prem=temp2;
        temp2->precedent=NULL;
    }
    free(temp1);
}

/**
@brief RecupererPremiereCarte permet de piocher la première carte du paquet
@param [in] l: pointeur sur liste
@return Carte
*/
CarteCourrier RecupererPremiereCarteC (ListeCourrier *l)
{
   assert (EstVideListeC(l)==0);

    CarteCourrier ValeurCarte;
    ValeurCarte=l->prem->info;
    SupprimerTeteListeC(l);
    return ValeurCarte;

}

